package com.frejoys.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frejoys.common.config.ValueConfig;
import com.frejoys.common.dto.admin.StoreResourceLibraryListDto;
import com.frejoys.common.dto.common.IdDto;
import com.frejoys.common.dto.common.resourcelibrary.ResourceLibraryListDto;
import com.frejoys.common.enums.EResourceLibrarySite;
import com.frejoys.common.enums.EResourceStatus;
import com.frejoys.common.enums.EStatus;
import com.frejoys.common.service.AliStorageService;
import com.frejoys.common.util.AppConfigUtil;
import com.frejoys.common.util.TimeUtil;
import com.frejoys.common.vo.admin.AdminResourceLibraryListVo;
import com.frejoys.common.vo.common.ResourceLibraryVo;
import com.frejoys.common.vo.store.ResourceLibraryListVo;
import com.frejoys.dao.entity.ResourceLibrary;
import com.frejoys.dao.mapper.ResourceLibraryMapper;
import com.frejoys.service.ResourceLibraryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

// 资源库
@Service
@RequiredArgsConstructor
public class ResourceLibraryServiceImpl extends ServiceImpl<ResourceLibraryMapper, ResourceLibrary> implements ResourceLibraryService {

    private final AliStorageService aliStorageService;

    private final ValueConfig valueConfig;


    @Override
    public boolean addInfo(Long userId, String name, Integer site) {
        return save(new ResourceLibrary(){{
            setUserId(userId);
            setName(name);
            setSite(site);
            setCreateTime(TimeUtil.unixTime());
        }});
    }

    @Override
    public boolean upStatus(Long userId, String name, Integer status) {
        LambdaUpdateWrapper<ResourceLibrary> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ResourceLibrary::getStatus, status);
        wrapper.eq(ResourceLibrary::getUserId, userId).eq(ResourceLibrary::getName, name);
        return update(wrapper);
    }

    @Override
    public boolean upStatus(String name, Integer status) {
        LambdaUpdateWrapper<ResourceLibrary> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ResourceLibrary::getStatus, status);
        wrapper.eq(ResourceLibrary::getName, name);
        return update(wrapper);
    }

    @Override
    public boolean upStatus(String name, Integer oldStatus, Integer newStatus) {
        LambdaUpdateWrapper<ResourceLibrary> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ResourceLibrary::getStatus, newStatus);
        wrapper.eq(ResourceLibrary::getName, name).eq(ResourceLibrary::getStatus, oldStatus);
        return update(wrapper);
    }

    @Override
    public boolean upStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<ResourceLibrary> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(ResourceLibrary::getStatus, status);
        wrapper.eq(ResourceLibrary::getId, id);
        return update(wrapper);
    }

    @Override
    public boolean delInfo(IdDto dto) {
        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ResourceLibrary::getName).eq(ResourceLibrary::getId, dto.getId());
        ResourceLibrary e = getOnly(wrapper);
        if (e != null) {
            return delInfo(e.getName());
        }
        return true;
    }

    @Override
    public boolean delInfo(String name) {
        if (StrUtil.isEmpty(name)) {
            return true;
        }
        name = AppConfigUtil.removeUrlPrefix(name);

        upStatus(name, EStatus.del.getValue());

        return aliStorageService.deleteFileToOss(name);
    }

    @Override
    public boolean delInfo(List<String> name) {
        if (name.isEmpty()) {
            return true;
        }
        name.forEach( e -> {
            delInfo(e);
        });
        return true;
    }

    @Override
    public ResourceLibraryVo getInfo(IdDto dto) {
        ResourceLibraryVo vo = null;

        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ResourceLibrary::getId, dto.getId());
        ResourceLibrary e = getOnly(wrapper);
        if (e != null) {
            vo = new ResourceLibraryVo();
            BeanUtil.copyProperties(e, vo);
        }
        return vo;
    }

    @Override
    public ResourceLibraryVo getInfo(Long userId, String name) {
        ResourceLibraryVo vo = null;

        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ResourceLibrary::getName, name);
        ResourceLibrary e = getOnly(wrapper);
        if (e != null) {
            vo = new ResourceLibraryVo();
            BeanUtil.copyProperties(e, vo);
        }
        return vo;
    }

    @Override
    public List<ResourceLibraryVo> listInfo(Long userId, ResourceLibraryListDto dto) {
        List<ResourceLibraryVo> list = new ArrayList<>();

        Page page = new Page<>(dto.getPage(), dto.getSize());
        page.setSearchCount(false);

        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();

        if (dto.getId() != null) {
            wrapper.eq(ResourceLibrary::getId, dto.getId());
        }

        if (userId != null) {
            wrapper.eq(ResourceLibrary::getUserId, userId);
        }

        if (!StrUtil.isEmpty(dto.getName())) {
            wrapper.eq(ResourceLibrary::getName, dto.getName());
        }

        if (dto.getSite() != null) {
            wrapper.eq(ResourceLibrary::getSite, dto.getSite());
        }

        if (!StrUtil.isEmpty(dto.getStartTime()) && !StrUtil.isEmpty(dto.getEndTime())) {
            wrapper.between(ResourceLibrary::getCreateTime, TimeUtil.unixTime(dto.getStartTime()), TimeUtil.unixTime(dto.getEndTime()));
        }

        if (dto.getStatus() != null) {
            wrapper.eq(ResourceLibrary::getStatus, dto.getStatus());
        }

        List<ResourceLibrary> records = baseMapper.selectPage(page, wrapper).getRecords();

        if (!records.isEmpty()) {
            for (ResourceLibrary e : records) {
                ResourceLibraryVo vo = new ResourceLibraryVo();
                BeanUtil.copyProperties(e, vo);
                list.add(vo);
            }
        }

        return list;
    }


    /** 查询资源库列表
     *
     * @param dto
     * @return
     */
    @Override
    public List<ResourceLibraryListVo> resourceLibraryListInfo(StoreResourceLibraryListDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());
        page.setSearchCount(false);

        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();

        wrapper.select(ResourceLibrary::getName,ResourceLibrary::getId)
                .eq(ResourceLibrary::getUserId, dto.getUserId());

        if (dto.getSite() != null) {
            wrapper.eq(ResourceLibrary::getSite, dto.getSite());
        }
        if (dto.getStatus() != null){
            wrapper.eq(ResourceLibrary::getStatus, dto.getStatus());
        }
        wrapper.orderByDesc(ResourceLibrary::getCreateTime);

        List<ResourceLibrary> records = baseMapper.selectPage(page, wrapper).getRecords();
        List<ResourceLibraryListVo> list = new ArrayList<>();

        if (!records.isEmpty()){
            records.forEach(resourceLibrary -> {
                ResourceLibraryListVo vo = new ResourceLibraryListVo();
                vo.setId(resourceLibrary.getId());
                vo.setFname(resourceLibrary.getName());
                vo.setFnameUrl(AppConfigUtil.getUrlPrefix(resourceLibrary.getName()));

                list.add(vo);
            });
        }
        return list;
    }

    @Override
    public IPage<AdminResourceLibraryListVo> adminResourceLibraryListInfo(StoreResourceLibraryListDto dto) {
        Page page = new Page<>(dto.getPage(), dto.getSize());

        LambdaQueryWrapper<ResourceLibrary> wrapper = new LambdaQueryWrapper<>();

        wrapper.select(ResourceLibrary::getName,ResourceLibrary::getId)
                .eq(ResourceLibrary::getUserId, dto.getUserId());

        if (dto.getSite() != null) {
            wrapper.eq(ResourceLibrary::getSite, dto.getSite());
        }
        if (dto.getStatus() != null){
            wrapper.eq(ResourceLibrary::getStatus, dto.getStatus());
        }
        wrapper.orderByDesc(ResourceLibrary::getCreateTime);

        Page<ResourceLibrary> records = baseMapper.selectPage(page, wrapper);
        IPage<AdminResourceLibraryListVo> voIPage = records.convert(resourceLibrary -> BeanUtil.copyProperties(resourceLibrary, AdminResourceLibraryListVo.class));
        List<AdminResourceLibraryListVo> list = voIPage.getRecords();

        if (!list.isEmpty()){
            list.forEach(resourceLibrary -> {
                resourceLibrary.setFnameUrl(AppConfigUtil.getUrlPrefix(resourceLibrary.getName()));
            });
        }
        return voIPage;
    }
}
